package com.example.demo.service;

import com.example.demo.model.Emp;
import com.example.demo.model.EmpCache;
import com.example.demo.reposition.EmpRedisRepos;
import com.example.demo.reposition.EmpReposition;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers.exact;

@Service
@Slf4j
public class EmpService {
    @Autowired
    EmpReposition empReposition;
    @Autowired
    EmpRedisRepos empRedisRepos;

    @Autowired
    private RedisTemplate<String, Emp> redisTemplate;

    public List<Emp> findAllEmps(){
        return empReposition.findAll();
    }

    public Optional<Emp> findOneFromCache(String name){
        Optional<EmpCache> cached = empRedisRepos.findOneByName(name);
        if (cached.isPresent()) {
            EmpCache coffeeCache = cached.get();
            Emp coffee = Emp.builder()
                    .name(coffeeCache.getName())
                    .job(coffeeCache.getJob())
                    .salary(coffeeCache.getSalary())
                    .build();
            log.info("Coffee {} found in cache.", coffeeCache);
            return Optional.of(coffee);
        } else {
            Optional<Emp> raw = findOne(name);
            raw.ifPresent(c -> {
                EmpCache coffeeCache = EmpCache.builder()
                        .id(c.getId())
                        .name(c.getName())
                        .job(c.getJob())
                        .salary(c.getSalary())
                        .build();
                log.info("Save Coffee {} to cache.", coffeeCache);
                empRedisRepos.save(coffeeCache);
            });
            return raw;
        }
    }

    public Optional<Emp> findOne(String name){
        ExampleMatcher ma = ExampleMatcher.matching()
                .withMatcher("name",exact().ignoreCase());
        Optional<Emp> opt = empReposition.findOne(Example.of(Emp.builder().name(name).build(),ma));
        log.info("db data");
        return opt;
    }
}
